﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;


namespace FFmpegVideoClip.Lib.Controls
{
    internal class TimeLineCurrentFragmentTickMark : TickBar
    {
        private DependencyPropertyDescriptor? MaxTimeDescriptor, CurrentZoomMinTimeDescriptor, CurrentZoomMaxTimeDescriptor;
        private TimeLineSlider? m_TimeLineSlider;
        //接收到的时间是以秒为单位的值
        private double StartTime, EndTime;
        public TimeLineCurrentFragmentTickMark() : base() { Loaded += TimeLineCurrentFragmentTickMark_Loaded; }
        private void TimeLineCurrentFragmentTickMark_Loaded(object sender, RoutedEventArgs e)
        {
            if (!Tools.GetParent(this, out m_TimeLineSlider))
                throw new InitializationExceptionException($"类型[{GetType().FullName}]的实例所在的父级中不存在[{typeof(TimeLineSlider).FullName}]");

            Loaded -= TimeLineCurrentFragmentTickMark_Loaded;
            MaxTimeDescriptor = DependencyPropertyDescriptor.FromProperty(TimeLineSlider.MaxTimeProperty, typeof(TimeLineSlider));
            MaxTimeDescriptor.AddValueChanged(m_TimeLineSlider, OnMaxTimeChange);

            CurrentZoomMinTimeDescriptor = DependencyPropertyDescriptor.FromProperty(TimeLineSlider.CurrentZoomMinTimeProperty, typeof(TimeLineSlider));
            CurrentZoomMinTimeDescriptor.AddValueChanged(m_TimeLineSlider, OnZoomMinTimeChange);

            CurrentZoomMaxTimeDescriptor = DependencyPropertyDescriptor.FromProperty(TimeLineSlider.CurrentZoomMaxTimeProperty, typeof(TimeLineSlider));
            CurrentZoomMaxTimeDescriptor.AddValueChanged(m_TimeLineSlider, OnZoomMaxTimeChange);

            ClipManage.CurrentEditFragment.PropertyChanged += CurrentEditFragment_PropertyChanged;
        }
        private void CurrentEditFragment_PropertyChanged(object? sender, PropertyChangedEventArgs e)
        {
            if (sender == null || string.IsNullOrWhiteSpace(e.PropertyName))
                return;
            Fragment fragment = (Fragment)sender;
            bool flag = false;
            double TempTime;
            if (e.PropertyName.Equals(nameof(fragment.StartTimeValue), StringComparison.OrdinalIgnoreCase))
            {
                TempTime = Tools.GetStringTimeToTimeSpan(fragment.StartTimeValue).TotalSeconds;
                if(TempTime!= StartTime)
                {
                    StartTime=TempTime;
                    flag = true;
                }
            }
            if (e.PropertyName.Equals(nameof(fragment.EndTimeValue), StringComparison.OrdinalIgnoreCase))
            {
                TempTime = Tools.GetStringTimeToTimeSpan(fragment.EndTimeValue).TotalSeconds;
                if (TempTime != EndTime)
                {
                    EndTime = TempTime;
                    flag = true;
                }
            }
            if (flag) InvalidateVisual();
        }

        private void OnMaxTimeChange(object? sender, EventArgs e) => MaxTime = sender == null ? TimeSpan.Zero : ((TimeLineSlider)sender).MaxTime;
        private void OnZoomMinTimeChange(object? sender, EventArgs e) => CurrentZoomMinTime = sender == null ? TimeSpan.Zero : ((TimeLineSlider)sender).CurrentZoomMinTime;
        private void OnZoomMaxTimeChange(object? sender, EventArgs e) => CurrentZoomMaxTime = sender == null ? TimeSpan.Zero : ((TimeLineSlider)sender).CurrentZoomMaxTime;

        [Bindable(true)] public TimeSpan MaxTime { get => (TimeSpan)GetValue(MaxTimeProperty); set => SetValue(MaxTimeProperty, value); }
        public static readonly DependencyProperty MaxTimeProperty = DependencyProperty.Register(nameof(MaxTime), typeof(TimeSpan), typeof(TimeLineCurrentFragmentTickMark), new PropertyMetadata(TimeSpan.Zero));

        [Bindable(true)] public TimeSpan CurrentZoomMinTime { get => (TimeSpan)GetValue(CurrentZoomMinTimeProperty); set => SetValue(CurrentZoomMinTimeProperty, value); }
        public static readonly DependencyProperty CurrentZoomMinTimeProperty = DependencyProperty.Register(nameof(CurrentZoomMinTime), typeof(TimeSpan), typeof(TimeLineCurrentFragmentTickMark), new PropertyMetadata(TimeSpan.Zero, (s, e) =>
        {
            TimeLineCurrentFragmentTickMark TickMark = (TimeLineCurrentFragmentTickMark)s;
            TimeSpan ts = (TimeSpan)e.NewValue;
            if (TickMark.Minimum != ts.TotalSeconds)
                TickMark.Minimum = ts.TotalSeconds;
        }));

        [Bindable(true)] public TimeSpan CurrentZoomMaxTime { get => (TimeSpan)GetValue(CurrentZoomMaxTimeProperty); set => SetValue(CurrentZoomMaxTimeProperty, value); }
        public static readonly DependencyProperty CurrentZoomMaxTimeProperty = DependencyProperty.Register(nameof(CurrentZoomMaxTime), typeof(TimeSpan), typeof(TimeLineCurrentFragmentTickMark), new PropertyMetadata(TimeSpan.Zero, (s, e) =>
        {
            TimeLineCurrentFragmentTickMark TickMark = (TimeLineCurrentFragmentTickMark)s;
            TimeSpan ts = (TimeSpan)e.NewValue;
            if (TickMark.Maximum != ts.TotalSeconds)
                TickMark.Maximum = ts.TotalSeconds;
        }));

        protected override void OnRender(DrawingContext m_drawingContext)
        {
            if (!(m_TimeLineSlider?.IsFileOpen ?? false) || Maximum - Minimum <= 0)
                return;

            double SecondsUIWidth = ActualWidth / (Maximum - Minimum);
            double UIPointX;

            UIPointX = (StartTime - Minimum) * SecondsUIWidth;
            m_drawingContext.DrawLine(new Pen(Fill,1), new(UIPointX, 0), new(UIPointX, ActualHeight));

            UIPointX = (EndTime - Minimum) * SecondsUIWidth;
            m_drawingContext.DrawLine(new Pen(Fill, 1), new(UIPointX, 0), new(UIPointX, ActualHeight));
        }


        [Serializable]
        public class InitializationExceptionException : Exception
        {
            public InitializationExceptionException() { }
            public InitializationExceptionException(string message) : base(message) { }
            public InitializationExceptionException(string message, Exception inner) : base(message, inner) { }
        }
    }
}
